// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UIStrategyService.cs" company="Open Trader">
//   Copyright (c) David Denis (david.denis@systemathics.com)
// </copyright>
// <summary>
//   |  Open Trader - The Open Source Systematic Trading Platform
//   |
//   |  This program is free software: you can redistribute it and/or modify
//   |  it under the terms of the GNU General Public License as published by
//   |  the Free Software Foundation, either version 2 of the License, or
//   |  (at your option) any later version.
//   |
//   |  This program is distributed in the hope that it will be useful,
//   |  but WITHOUT ANY WARRANTY; without even the implied warranty of
//   |  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//   |  GNU General Public License for more details.
//   |
//   |  You should have received a copy of the GNU General Public License
//   |  along with this program.  If not, see http://www.gnu.org/licenses
//   |
//   |  Up to date informations about Open Trader can be found at :
//   |    http://opentrader.org
//   |    http://opentrader.codeplex.com
//   |
//   |  For professional services, please visit us at :
//   |    http://www.systemathics.com
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Org.OpenTrader.Framework.Forge.UI.Forms
{
    #region Using Directives

    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Linq;
    using System.Reflection;

    using Org.OpenTrader.Framework.Enums;
    using Org.OpenTrader.Framework.Events;
    using Org.OpenTrader.Framework.Forge.Interfaces;
    using Org.OpenTrader.Framework.UI.Forms;

    #endregion

    /// <summary>
    /// The ui strategy service.
    /// </summary>
    public partial class UIStrategyService : UIControl
    {
        #region Constants and Fields

        /// <summary>
        /// The instruments expos.
        /// </summary>
        private IDictionary<Guid, UIInstrumentListExpo> instrumentsExpos = new Dictionary<Guid, UIInstrumentListExpo>();

        /// <summary>
        /// The instruments trackers.
        /// </summary>
        private IDictionary<Guid, UIInstrumentListOrderTracker> instrumentsTrackers = new Dictionary<Guid, UIInstrumentListOrderTracker>();

        #endregion

        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="UIStrategyService"/> class.
        /// </summary>
        public UIStrategyService()
        {
            this.InitializeComponent();
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="UIStrategyService"/> class.
        /// </summary>
        /// <param name="strategyService">
        /// The strategyService.
        /// </param>
        public UIStrategyService(IStrategyService strategyService)
        {
            this.StrategyService = strategyService;
            this.InitializeComponent();
        }

        #endregion

        #region Delegates

        /// <summary>
        /// The start stop delegate.
        /// </summary>
        private delegate Status CreateDestroyDelegate();

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets StrategyService.
        /// </summary>
        private IStrategyService StrategyService { get; set; }

        #endregion

        #region Methods

        /// <summary>
        /// The ui virtual grid 1_ cell click.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void OnVirtualGrid1CellClick(object sender, System.Windows.Forms.DataGridViewCellEventArgs e)
        {
            if (this.StrategyService == null)
            {
                return;
            }

            if (e.RowIndex >= this.StrategyService.Plugins.Length)
            {
                return;
            }

            // The strategy itself
            var strategyPlugin = this.StrategyService.Plugins[e.RowIndex] as IStrategyPlugin;

            // The tracking structure maintained by the service for current strategy
            var strategyPluginTrackingCell = this.StrategyService.TrackingCells[strategyPlugin.Descriptor.ID];

            // stop/start buttons
            switch (e.ColumnIndex)
            {
                case 4:
                    {
                        switch (strategyPluginTrackingCell.State)
                        {
                            case EStrategyState.Destroyed:
                                var start = new CreateDestroyDelegate(strategyPluginTrackingCell.Create);
                                start.BeginInvoke(null, null);
                                break;

                            case EStrategyState.Created:
                                var stop = new CreateDestroyDelegate(strategyPluginTrackingCell.Destroy);
                                stop.BeginInvoke(null, null);
                                break;
                        }
                    }

                    break;

                case 6:
                    {
                        // Instruments Expositions
                        if (! this.instrumentsExpos.ContainsKey(strategyPlugin.Descriptor.ID))
                        {
                            var newuicontrol = new UIInstrumentListExpo();
                            var uiform = newuicontrol.CreateContainingForm(
                                string.Format("Instruments Expositions for strategy {0}", strategyPlugin.Name), 
                                EUIFormLayoutType.TitleBarAtTop, 
                                EUIFormClosingType.Soft);

                            this.instrumentsExpos[strategyPlugin.Descriptor.ID] = newuicontrol;
                        }

                        var uicontrol = this.instrumentsExpos[strategyPlugin.Descriptor.ID];
                        uicontrol.Instruments = strategyPlugin.Referential.Instruments;
                        uicontrol.ContainingForm.Visibility = EUIFormVisibility.Invert;
                    }

                    break;

                case 7:
                    {
                        // Instruments Trackers
                        if (!this.instrumentsTrackers.ContainsKey(strategyPlugin.Descriptor.ID))
                        {
                            var newuicontrol = new UIInstrumentListOrderTracker();
                            var uiform = newuicontrol.CreateContainingForm(
                                string.Format("Instruments Trackers for strategy {0}", strategyPlugin.Name), 
                                EUIFormLayoutType.TitleBarAtTop, 
                                EUIFormClosingType.Soft);

                            this.instrumentsTrackers[strategyPlugin.Descriptor.ID] = newuicontrol;
                        }

                        var uicontrol = this.instrumentsTrackers[strategyPlugin.Descriptor.ID];
                        uicontrol.Instruments = strategyPlugin.Referential.Instruments;
                        uicontrol.ContainingForm.Visibility = EUIFormVisibility.Invert;
                    }

                    break;
            }
        }

        /// <summary>
        /// The ui virtual grid 1_ ui grid query cell info.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void OnVirtualGrid1UIGridQueryCellInfo(object sender, VirtualGridEventArgs.QueryCellInfo e)
        {
            if (this.StrategyService == null)
            {
                return;
            }

            if (e.RowIndex >= this.StrategyService.Plugins.Length)
            {
                return;
            }

            // The strategy itself
            var strategyPlugin = this.StrategyService.Plugins[e.RowIndex] as IStrategyPlugin;
            if (strategyPlugin == null)
            {
                return;
            }

            // The tracking structure maintained by the service for current strategy
            var strategyPluginTrackingCell = this.StrategyService.TrackingCells[strategyPlugin.Descriptor.ID];

            // type
            var strategyPluginType = strategyPlugin.GetType();

            switch (e.ColumnIndex)
            {
                case 0: // name
                    e.Value = strategyPlugin.Name;
                    break;

                case 1: // class
                    e.Value = strategyPluginType.Name;
                    e.ToolTip = strategyPluginType.FullName;
                    break;

                case 2: // assembly
                    var aname = new AssemblyName(strategyPluginType.Assembly.FullName);
                    e.Value = aname.Name.Split('.').Last();
                    e.ToolTip = strategyPluginType.Assembly.FullName;
                    break;

                case 3: // Status
                    e.Value = strategyPluginTrackingCell.State;
                    break;

                case 4: // Control button
                    if (strategyPluginTrackingCell.IsCreated)
                    {
                        e.Value = "Destroy";
                        this.uiVirtualGrid1[e.ColumnIndex, e.RowIndex].Style.BackColor = Color.LightGreen;
                    }
                    else if (strategyPluginTrackingCell.IsDestroyed)
                    {
                        e.Value = "Create";
                        this.uiVirtualGrid1[e.ColumnIndex, e.RowIndex].Style.BackColor = Color.Orange;
                    }
                    else
                    {
                        this.uiVirtualGrid1[e.ColumnIndex, e.RowIndex].Style.BackColor = Color.Yellow;
                        e.Value = "Wait";
                    }

                    break;

                case 5: // Strategy Expo
                    e.Value = ">>";
                    break;

                case 6: // Instruments Expo
                    e.Value = ">>";
                    break;

                case 7: // Instruments Trackers
                    e.Value = ">>";
                    break;
            }
        }

        /// <summary>
        /// The ui virtual grid 1_ ui grid query row count.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void OnVirtualGrid1UIGridQueryRowCount(object sender, VirtualGridEventArgs.QueryRowCount e)
        {
            if (this.StrategyService != null)
            {
                e.RowCount = this.StrategyService.Plugins.Length;
            }
        }

        #endregion
    }
}